package top.ffhome.blog.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.hutool.core.util.ObjectUtil;
import eu.bitwalker.useragentutils.UserAgent;
import top.ffhome.blog.entity.Article;
import top.ffhome.blog.entity.ViewArticle;
import top.ffhome.blog.mapper.ArticleMapper;
import top.ffhome.blog.mapper.ViewArticleMapper;
import top.ffhome.blog.service.ArticleService;
import top.ffhome.common.audit.AuditService;
import top.ffhome.common.exception.BusinessException;
import top.ffhome.common.page.PageRequest;
import top.ffhome.common.page.PageResult;
import top.ffhome.common.service.impl.BaseServiceImpl;
import top.ffhome.common.utils.IpUtils;
import top.ffhome.system.config.shiro.ShiroUtil;
import top.ffhome.util.core.UEditorUtil;

@Service
@AuditService(entity = Article.class)
public class ArticleServiceImpl extends BaseServiceImpl<Article, ArticleMapper> implements ArticleService {
	@Autowired
	private ViewArticleMapper viewArticleMapper;

	@Override
	protected void afterGet(Article entity) {
		super.afterGet(entity);
		if (ShiroUtil.isAuthenticated() && !ShiroUtil.check("blog:article:viewAll")) {
			if (!entity.getCreateBy().equals(currentUser.getId())) {
				throw new BusinessException("只能查看自己的博文");
			}
		}
	}

	@Override
	protected void beforeSelectParam(Map<String, Object> params) {
		if (ShiroUtil.isAuthenticated()) {
			if (!ShiroUtil.check("blog:article:viewAll")) {
				params.put("authSQL", " and a.create_by=" + currentUser.getId());
			}
		} else {
			if (!params.containsKey("createBy")) {
				params.put("createBy", 0);
			}
		}
		super.beforeSelectParam(params);
	}

	@Override
	protected void beforeUpdate(Article entity) {
		if (!ShiroUtil.check("blog:article:viewAll")) {
			entity.setCreateBy(currentUser.getId());
		}
		super.beforeUpdate(entity);
	}

	@Override
	@CacheEvict(value = { "label_selectLabelsByCreateBy" }, allEntries = true)
	public void clearCache() {
	}

	@Override
	protected void beforeSave(Article entity) {
		entity.setContent(UEditorUtil.highlight(entity.getContent()));
		super.beforeSave(entity);
	}

	@Override
	protected void afterSave(Article entity) {
		saveLabelRelation(entity);
		super.afterSave(entity);
	}

	@Override
	protected void afterDelete(List<Long> ids) {
		for (Long id : ids) {
			mapper.deleteLabelRelation(id);
		}
		super.afterDelete(ids);
	}

	/**
	 * 保存博文与标签关联处理
	 * 
	 * @param entity
	 */
	private void saveLabelRelation(Article entity) {
		if (entity.getLabelIds() == null || entity.getLabelIds().size() == 0) {
			return;
		}
		mapper.deleteLabelRelation(entity.getId());
		mapper.insertLabelRelation(entity.getId(), entity.getLabelIds());
	}

	@Override
	public Set<Long> selectLabelsByArticleId(Long articleId) {
		return mapper.selectLabelsByArticleId(articleId);
	}

	@Override
	public PageResult<Article> select(PageRequest request) {
		Object labelId = request.getParams().get("labelId");
		if (ObjectUtil.isNotEmpty(labelId)) {
			request.getParams().put("joinArticleLabel", "Y");
		}
		return super.select(request);
	}

	@Override
	public void addCount(Long articleId) {
		mapper.addCount(articleId);
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
		viewArticleMapper.insert(new ViewArticle(articleId, IpUtils.getIp(), userAgent.getBrowser().getName(),
				userAgent.getOperatingSystem().getName()));
	}
}
